<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Redis 管理面板</title>
    <style>
        :root {
            --bg-primary: #121212;
            --bg-secondary: #1e1e1e;
            --bg-card: #252526;
            --bg-modal: #2d2d30;
            --text-primary: #e0e0e0;
            --text-secondary: #a0a0a0;
            --accent-primary: #4caf50;
            --accent-secondary: #2196f3;
            --accent-warning: #ff9800;
            --accent-danger: #f44336;
            --accent-info: #3f51b5;
            --border-color: #3c3c3c;
            --hover-bg: #333333;
        }

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background-color: var(--bg-primary);
            color: var(--text-primary);
            line-height: 1.6;
            padding: 20px;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
            background-color: var(--bg-card);
            padding: 25px;
            border-radius: 10px;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
        }

        h1 {
            color: var(--accent-primary);
            text-align: center;
            margin-bottom: 25px;
            font-size: 28px;
            font-weight: 600;
        }

        .controls {
            display: flex;
            gap: 15px;
            margin-bottom: 25px;
            flex-wrap: wrap;
            justify-content: center;
        }

        .btn {
            padding: 10px 20px;
            border: none;
            border-radius: 6px;
            cursor: pointer;
            font-size: 15px;
            font-weight: 500;
            transition: all 0.3s ease;
            display: inline-flex;
            align-items: center;
            gap: 8px;
        }

        .btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
        }

        .btn-primary {
            background-color: var(--accent-primary);
            color: white;
        }

        .btn-primary:hover {
            background-color: #43a047;
        }

        .btn-secondary {
            background-color: var(--accent-secondary);
            color: white;
        }

        .btn-secondary:hover {
            background-color: #1e88e5;
        }

        .btn-warning {
            background-color: var(--accent-warning);
            color: white;
        }

        .btn-warning:hover {
            background-color: #ef6c00;
        }

        .btn-danger {
            background-color: var(--accent-danger);
            color: white;
        }

        .btn-danger:hover {
            background-color: #e53935;
        }

        .btn-info {
            background-color: var(--accent-info);
            color: white;
        }

        .btn-info:hover {
            background-color: #303f9f;
        }

        .nav-link {
            background-color: var(--accent-secondary);
            color: white;
            text-decoration: none;
            border-radius: 6px;
            font-weight: 500;
            transition: all 0.3s ease;
        }

        .nav-link:hover {
            background-color: #1e88e5;
            transform: translateY(-2px);
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
        }

        table {
            width: 100%;
            border-collapse: separate;
            border-spacing: 0;
            border-radius: 8px;
            overflow: hidden;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
            table-layout: fixed;
        }

        th {
            background-color: var(--bg-secondary);
            color: var(--accent-primary);
            font-weight: 600;
            text-align: left;
            padding: 16px 20px;
        }

        td {
            padding: 16px 20px;
            border-bottom: 1px solid var(--border-color);
            word-wrap: break-word;
            word-break: break-all;
        }

        tr:last-child td {
            border-bottom: none;
        }

        tr:hover {
            background-color: var(--hover-bg);
        }

        .key-name {
            color: var(--accent-secondary);
            cursor: pointer;
            font-weight: 500;
            transition: color 0.2s;
            word-wrap: break-word;
            word-break: break-all;
            white-space: normal;
        }

        .key-name:hover {
            color: #64b5f6;
            text-decoration: underline;
        }

        .key-name-col {
            width: 70%;
        }

        .key-type-col {
            width: 15%;
        }

        .key-action-col {
            width: 15%;
        }

        .loading {
            text-align: center;
            color: var(--text-secondary);
            font-style: italic;
            padding: 30px;
        }

        .error {
            color: #ff8a80;
            background-color: rgba(244, 67, 54, 0.15);
            padding: 15px;
            border-radius: 6px;
            margin: 15px 0;
            border-left: 4px solid var(--accent-danger);
        }

        .success {
            color: #a5d6a7;
            background-color: rgba(76, 175, 80, 0.15);
            padding: 15px;
            border-radius: 6px;
            margin: 15px 0;
            border-left: 4px solid var(--accent-primary);
        }

        input[type="text"], input[type="password"], input[type="number"] {
            padding: 10px 15px;
            border-radius: 6px;
            border: 1px solid var(--border-color);
            background-color: var(--bg-secondary);
            color: var(--text-primary);
            font-size: 15px;
            width: 100%;
            box-sizing: border-box;
        }

        input:focus {
            outline: none;
            border-color: var(--accent-primary);
            box-shadow: 0 0 0 2px rgba(76, 175, 80, 0.2);
        }

        .modal {
            display: none;
            position: fixed;
            z-index: 1000;
            left: 0;
            top: 0;
            width: 100%;
            height: 100%;
            overflow: auto;
            background-color: rgba(0, 0, 0, 0.7);
            backdrop-filter: blur(5px);
        }

        .modal-content {
            background-color: var(--bg-modal);
            margin: 5% auto;
            padding: 30px;
            border-radius: 10px;
            width: 90%;
            max-width: 800px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
            border: 1px solid var(--border-color);
            position: relative;
        }

        .close {
            color: var(--text-secondary);
            float: right;
            font-size: 32px;
            font-weight: bold;
            cursor: pointer;
            position: absolute;
            top: 15px;
            right: 25px;
            transition: color 0.2s;
        }

        .close:hover {
            color: var(--text-primary);
        }

        .config-form {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 20px;
            margin-top: 20px;
        }

        @media (max-width: 768px) {
            .config-form {
                grid-template-columns: 1fr;
            }
        }

        .form-group {
            margin-bottom: 15px;
        }

        .form-group label {
            display: block;
            margin-bottom: 8px;
            font-weight: 500;
            color: var(--text-primary);
        }

        .value-item {
            border: 1px solid var(--border-color);
            padding: 15px;
            margin: 15px 0;
            background-color: var(--bg-secondary);
            border-radius: 6px;
            word-break: break-all;
            word-wrap: break-word;
            max-width: 100%;
        }

        .value-header {
            font-weight: 700;
            margin-bottom: 10px;
            color: var(--accent-secondary);
        }

        .delete-btn {
            background-color: var(--accent-danger);
            color: white;
            border: none;
            padding: 8px 12px;
            border-radius: 4px;
            cursor: pointer;
            font-weight: 500;
            height: fit-content;
            transition: background-color 0.2s;
            flex-shrink: 0;
        }

        .delete-btn:hover {
            background-color: #e53935;
        }

        .remove-btn {
            background-color: var(--accent-danger);
            color: white;
            border: none;
            padding: 8px 12px;
            border-radius: 4px;
            cursor: pointer;
            font-weight: 500;
            height: fit-content;
            transition: background-color 0.2s;
            flex-shrink: 0;
        }

        .remove-btn:hover {
            background-color: #e53935;
        }

        .card {
            background-color: var(--bg-card);
            border-radius: 10px;
            padding: 25px;
            margin-bottom: 25px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
        }

        .card-title {
            font-size: 20px;
            margin-bottom: 20px;
            color: var(--accent-primary);
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .search-box {
            display: flex;
            gap: 10px;
            margin-bottom: 25px;
            flex-wrap: wrap;
        }

        .search-box input {
            flex: 1;
            min-width: 200px;
        }

        .key-type {
            font-size: 12px;
            background-color: var(--accent-warning);
            color: #000;
            padding: 3px 7px;
            border-radius: 4px;
            font-weight: bold;
        }

        .empty-state {
            text-align: center;
            padding: 40px 20px;
            color: var(--text-secondary);
        }

        .empty-state-icon {
            font-size: 48px;
            margin-bottom: 15px;
            opacity: 0.5;
        }
        
        .insert-form {
            background-color: var(--bg-secondary);
            padding: 20px;
            border-radius: 8px;
            margin-bottom: 25px;
            display: none;
        }
        
        .insert-form.active {
            display: block;
        }
        
        .form-row {
            display: flex;
            gap: 15px;
            margin-bottom: 15px;
            flex-wrap: wrap;
        }
        
        .form-row > div {
            flex: 1;
            min-width: 200px;
        }
        
        textarea {
            padding: 10px 15px;
            border-radius: 6px;
            border: 1px solid var(--border-color);
            background-color: var(--bg-secondary);
            color: var(--text-primary);
            font-size: 15px;
            width: 100%;
            box-sizing: border-box;
            min-height: 100px;
            resize: vertical;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>💾 Redis 管理面板</h1>
        <div class="controls">
            <button class="btn btn-warning" onclick="window.location.href='/'">🔄 切换到 RabbitMQ 管理</button>
            <button class="btn btn-secondary" onclick="showConfigModal()">⚙️ 配置连接</button>
            <button class="btn btn-secondary" onclick="loadKeys()">↻ 刷新键列表</button>
            <button class="btn btn-primary" onclick="toggleInsertForm()">➕ 插入键值</button>
            <button class="btn btn-info" onclick="window.location.href='/file.html'">📁 文件查看器</button>
        </div>
        
        <div id="insertForm" class="insert-form">
            <h3>新增键值对</h3>
            <div class="form-row">
                <div>
                    <label for="insertKey">键名:</label>
                    <input type="text" id="insertKey" placeholder="请输入键名">
                </div>
                <div>
                    <label for="insertValue">值:</label>
                    <textarea id="insertValue" placeholder="请输入值"></textarea>
                </div>
            </div>
            <div style="text-align: center;">
                <button class="btn btn-primary" onclick="insertKeyValue()">💾 保存</button>
                <button class="btn btn-secondary" onclick="toggleInsertForm()">取消</button>
            </div>
        </div>
        
        <div class="search-box">
            <input type="text" id="pattern" placeholder="输入键匹配模式，如 * 或 user:*" value="*">
            <button class="btn btn-primary" onclick="loadKeys()">🔍 搜索</button>
        </div>

        <div id="statusMessage"></div>
        
        <div id="keyList">
            <p class="loading">⏳ 正在加载键列表...</p>
        </div>
    </div>

    <!-- 配置模态框 -->
    <div id="configModal" class="modal">
        <div class="modal-content">
            <span class="close" onclick="closeConfigModal()">&times;</span>
            <h2>⚙️ Redis 连接配置</h2>
            <div id="configMessage"></div>
            <form id="configForm" class="config-form">
                <div class="form-group">
                    <label for="host">🖥️ 主机地址:</label>
                    <input type="text" id="host" value="localhost" required>
                </div>
                
                <div class="form-group">
                    <label for="port">🔌 端口:</label>
                    <input type="number" id="port" value="6379" required>
                </div>
                
                <div class="form-group">
                    <label for="password">🔒 密码:</label>
                    <input type="password" id="password" value="">
                </div>
                
                <div class="form-group">
                    <label for="database">🗃️ 数据库:</label>
                    <input type="number" id="database" value="0" min="0" max="15" required>
                </div>
                
                <div style="grid-column: span 2; text-align: center; margin-top: 10px;">
                    <button type="button" class="btn btn-primary" onclick="saveConfig()">💾 保存配置</button>
                </div>
            </form>
        </div>
    </div>

    <!-- 键值内容模态框 -->
    <div id="valueModal" class="modal">
        <div class="modal-content">
            <span class="close" onclick="closeValueModal()">&times;</span>
            <h3>📋 键 "<span id="modalKeyName"></span>" 的值</h3>
            <div id="valueContent">
                <p class="loading">⏳ 正在加载值...</p>
            </div>
        </div>
    </div>

    <script>
        // 页面加载完成后自动加载键列表
        window.onload = function() {
            loadKeys();
        };

        // 显示配置模态框
        function showConfigModal() {
            document.getElementById('configModal').style.display = 'block';
        }

        // 关闭配置模态框
        function closeConfigModal() {
            document.getElementById('configModal').style.display = 'none';
        }

        // 关闭键值模态框
        function closeValueModal() {
            document.getElementById('valueModal').style.display = 'none';
        }
        
        // 切换插入表单显示状态
        function toggleInsertForm() {
            const form = document.getElementById('insertForm');
            form.classList.toggle('active');
        }
        
        // 插入键值对
        function insertKeyValue() {
            const key = document.getElementById('insertKey').value.trim();
            const value = document.getElementById('insertValue').value.trim();
            
            if (!key) {
                alert('请输入键名');
                return;
            }
            
            if (!value) {
                alert('请输入值');
                return;
            }
            
            fetch('/api/redis/keys', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                },
                body: `key=${encodeURIComponent(key)}&value=${encodeURIComponent(value)}`
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    alert('键值对插入成功');
                    toggleInsertForm(); // 隐藏表单
                    document.getElementById('insertKey').value = ''; // 清空输入
                    document.getElementById('insertValue').value = ''; // 清空输入
                    loadKeys(); // 刷新键列表
                } else {
                    alert('插入失败: ' + (data.error || data.message));
                }
            })
            .catch(error => {
                alert('插入时出错: ' + error.message);
            });
        }

        // 关闭模态框当用户点击模态框外部
        window.onclick = function(event) {
            var configModal = document.getElementById('configModal');
            var valueModal = document.getElementById('valueModal');
            if (event.target == configModal) {
                configModal.style.display = 'none';
            }
            if (event.target == valueModal) {
                valueModal.style.display = 'none';
            }
        }

        // 保存配置
        function saveConfig() {
            const host = document.getElementById('host').value;
            const port = document.getElementById('port').value;
            const password = document.getElementById('password').value;
            const database = document.getElementById('database').value;
            
            // 发送配置到后端
            fetch('/api/redis/config', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                },
                body: `host=${encodeURIComponent(host)}&port=${encodeURIComponent(port)}&password=${encodeURIComponent(password)}&database=${encodeURIComponent(database)}`
            })
            .then(response => response.text())
            .then(data => {
                document.getElementById('configMessage').innerHTML = '<div class="success">✅ ' + data + '</div>';
                setTimeout(() => {
                    document.getElementById('configModal').style.display = 'none';
                    document.getElementById('configMessage').innerHTML = '';
                    loadKeys(); // 重新加载键列表
                }, 1000);
            })
            .catch(error => {
                document.getElementById('configMessage').innerHTML = '<div class="error">❌ 配置保存失败: ' + error + '</div>';
            });
        }

        // 加载键列表
        function loadKeys() {
            const pattern = document.getElementById('pattern').value || '*';
            document.getElementById('keyList').innerHTML = '<p class="loading">⏳ 正在加载键列表...</p>';
            
            fetch(`/api/redis/keys?pattern=${encodeURIComponent(pattern)}`)
                .then(response => {
                    if (!response.ok) {
                        throw new Error('Network response was not ok');
                    }
                    return response.json();
                })
                .then(data => {
                    const keyListDiv = document.getElementById('keyList');
                    if (data && Array.isArray(data)) {
                        if (data.length > 0) {
                            let tableHtml = `
                                <table>
                                    <thead>
                                        <tr>
                                            <th class="key-name-col">键名</th>
                                            <th class="key-type-col">类型</th>
                                            <th class="key-action-col">操作</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                            `;
                            
                            data.forEach(key => {
                                // 兼容不同的数据格式
                                const keyName = typeof key === 'string' ? key : (key.name || key);
                                const keyType = typeof key === 'string' ? '' : (key.type || '');
                                
                                tableHtml += `
                                    <tr>
                                        <td class="key-name-col">
                                            <div class="key-name" onclick="viewKeyValue('${keyName}')">${escapeHtml(keyName)}</div>
                                        </td>
                                        <td class="key-type-col">
                                            ${keyType ? `<span class="key-type">${keyType}</span>` : ''}
                                        </td>
                                        <td class="key-action-col">
                                            <button class="remove-btn" onclick="deleteKey('${keyName}')">🗑️ 删除</button>
                                        </td>
                                    </tr>
                                `;
                            });
                            
                            tableHtml += `
                                    </tbody>
                                </table>
                            `;
                            
                            keyListDiv.innerHTML = tableHtml;
                        } else {
                            keyListDiv.innerHTML = `
                                <div class="empty-state">
                                    <div class="empty-state-icon">📭</div>
                                    <h3>未找到匹配的键</h3>
                                    <p>请尝试其他搜索模式</p>
                                </div>
                            `;
                        }
                    } else {
                        keyListDiv.innerHTML = '<div class="error">获取键列表失败</div>';
                    }
                })
                .catch(error => {
                    console.error('Error loading keys:', error);
                    document.getElementById('keyList').innerHTML = '<div class="error">加载键列表失败: ' + error.message + '</div>';
                });
        }

        // 查看键值
        function viewKeyValue(key) {
            document.getElementById('modalKeyName').textContent = key;
            document.getElementById('valueContent').innerHTML = '<p class="loading">⏳ 正在加载值...</p>';
            document.getElementById('valueModal').style.display = 'block';
            
            fetch(`/api/redis/keys/${encodeURIComponent(key)}`)
                .then(response => {
                    if (!response.ok) {
                        throw new Error('Network response was not ok');
                    }
                    return response.json();
                })
                .then(data => {
                    const contentDiv = document.getElementById('valueContent');
                    if (data && typeof data === 'object') {
                        // 提取TTL、类型和值
                        const ttl = data.ttl !== undefined ? data.ttl : 'N/A';
                        const type = data.type || 'unknown';
                        const value = data.value !== undefined ? data.value : 'N/A';
                        
                        // 格式化TTL显示
                        let ttlDisplay = 'N/A';
                        if (ttl === -1) {
                            ttlDisplay = '永不过期';
                        } else if (ttl === -2) {
                            ttlDisplay = '键不存在';
                        } else if (ttl >= 0) {
                            ttlDisplay = `${ttl} 秒`;
                        }
                        
                        contentDiv.innerHTML = `
                            <div class="value-item">
                                <div class="value-header">📋 类型</div>
                                <div>${escapeHtml(type)}</div>
                            </div>
                            <div class="value-item">
                                <div class="value-header">⏱️ 剩余过期时间</div>
                                <div>${escapeHtml(ttlDisplay)}</div>
                            </div>
                            <div class="value-item">
                                <div class="value-header">📄 值内容</div>
                                <div>${escapeHtml(JSON.stringify(value, null, 2))}</div>
                            </div>
                            <button class="btn btn-danger" onclick="deleteKey('${key}', true)" style="margin-top: 15px;">🗑️ 删除此键</button>
                        `;
                    } else {
                        contentDiv.innerHTML = '<div class="error">获取键详情失败</div>';
                    }
                })
                .catch(error => {
                    console.error('Error fetching key value:', error);
                    document.getElementById('valueContent').innerHTML = '<div class="error">获取键值失败: ' + error.message + '</div>';
                });
        }

        // 删除键
        function deleteKey(key, closeModal) {
            if (confirm(`确定要删除键 "${key}" 吗？`)) {
                fetch(`/api/redis/keys/${encodeURIComponent(key)}`, {
                    method: 'DELETE'
                })
                .then(response => {
                    if (!response.ok) {
                        throw new Error('Network response was not ok');
                    }
                    return response.json();
                })
                .then(data => {
                    if (data.success) {
                        alert('键删除成功');
                        if (closeModal) {
                            document.getElementById('valueModal').style.display = 'none';
                        }
                        loadKeys(); // 重新加载键列表
                    } else {
                        alert('键删除失败: ' + (data.error || data.message));
                    }
                })
                .catch(error => {
                    alert('删除键时出错: ' + error.message);
                });
            }
        }
        
        // 转义HTML特殊字符
        function escapeHtml(text) {
            const map = {
                '&': '&amp;',
                '<': '&lt;',
                '>': '&gt;',
                '"': '&quot;',
                "'": '&#039;'
            };
            
            return text.replace(/[&<>"']/g, function(m) { return map[m]; });
        }
    </script>
</body>
</html>